---
const { prompt = "", eswd = { phrase: "empty", misssings: [] } } = Astro.props;
---

<xlate-prompt data-eswd={eswd}>
  <main>
    <h1>Fill in the <span class="text-gradient">words</span></h1>
    <div>
      <button id="reload">reload</button>
      <select name="mode" id="mode">
        <option value="single-direct">single/direct</option>
        <option value="single-accept">single/accept</option>
      </select>
      <span id="debug">debug</span>
    </div>
    <p id="prompt" class="prompt">{prompt}</p>
    <div id="textfield" class="textfield" contenteditable="true"></div>
    <button>check</button>
  </main>
</xlate-prompt>

<script>
  // Work in progress
  // FIXME (critical): entering composed letters with diacritics doesn't work at all, no idea why.

  class XlatePrompt extends HTMLElement {
    constructor() {
      super();

      const eswd = JSON.parse(this.dataset.eswd ?? "{}");

      console.log(eswd);

      let position = { gap: 0, pos: 0 };

      const textfield = document.querySelector("#textfield")!;
      textfield.innerHTML = eswd.phrase;

      function replacei(str: string, i: number, a: string): string {
        return str.substring(0, i) + a + str.substring(i + 1, str.length);
      }

      /**
       * See:
       *
       * https://www.davidbcalhoun.com/2019/matching-accented-strings-in-javascript/
       * https://stackoverflow.com/questions/990904/remove-accents-diacritics-in-a-string-in-javascript/37511463#37511463
       *
       */
      const removeDiacritics = (str: string) => {
        return (
          str
            .normalize("NFD")
            .replace(/[\u0300-\u036f]/g, "")
            // special case: the Polish letter "ł" is not a composed character!
            .replace(/\u0142/g, "l")
        );
      };

      function checkWord(should: string, is: string): boolean {
        const shouldRd = removeDiacritics(should.toLowerCase());
        const isRd = removeDiacritics(is.toLowerCase());
        console.log("checking", shouldRd, isRd);
        for (var i = 0; i < shouldRd.length; i++) {
          if (isRd[i] == ".") continue;
          if (isRd[i] != shouldRd[i]) return false;
        }
        return true;
      }

      function handleLetter(a: string) {
        const span = document.querySelector(`#span${position.gap}`);

        if (span instanceof HTMLSpanElement) {
          if (
            position.pos == span.innerText.length &&
            position.gap < eswd.missings.length - 1
          ) {
            position.pos = 0;
            position.gap += 1;
            handleLetter(a);
          } else if (position.pos < span.innerText.length) {
            span.innerText = replacei(span.innerText, position.pos, a);
            position.pos += 1;

            colorCurrentGap();
          } else {
            if (position.gap < eswd.missings.length - 1) {
              position.pos = 0;
              position.gap += 1;
            }
          }
        }
      }

      function colorCurrentGap() {
        const span = document.querySelector(`#span${position.gap}`);

        if (!(span instanceof HTMLSpanElement)) return;
        const wordOkay = checkWord(eswd.missings[position.gap], span.innerText);

        if (wordOkay) {
          span.classList.remove("gap");
          span.classList.add("right");
        } else {
          span.classList.add("gap");
          span.classList.remove("right");
        }
      }

      function handleBackspace() {
        const span = document.querySelector(`#span${position.gap}`);

        if (span instanceof HTMLSpanElement) {
          if (position.pos == -1) {
            position.pos = span.innerText.length;
          }

          if (position.pos > 0) {
            span.innerText = replacei(span.innerText, position.pos - 1, ".");
            colorCurrentGap();
            position.pos -= 1;
          } else if (position.pos == 0 && position.gap > 0) {
            position.gap -= 1;
            position.pos = -1;
            handleBackspace();
          }
        }
      }

      function handleKey(event: KeyboardEvent) {
        switch (event.key) {
          case "Backspace":
            handleBackspace();
            break;
          case "Tab":
            break;
          case "Process":
            break;
          default:
            if (event.key.length === 1) {
              handleLetter(event.key);
            } else {
              console.log("unhandled key", event.key);
            }
        }

        const debug = document.querySelector("#debug")!;
        debug.innerHTML = `${JSON.stringify(position)}`;
      }

      textfield?.addEventListener("input", (event) => {
        event.preventDefault();
      });

      textfield?.addEventListener("keydown", (event) => {
        event.preventDefault();
      });

      textfield?.addEventListener("keyup", (event) => {
        if (event instanceof KeyboardEvent) {
          handleKey(event);
        }
        event.preventDefault();
      });

      document.getElementById("textfield")!.focus();
      var sel = document.getSelection();
      console.log(sel);
      var range = sel?.getRangeAt(0);
      console.log(range);
    }
  }

  customElements.define("xlate-prompt", XlatePrompt);
</script>

<script>
  document.getElementById("reload")?.addEventListener("click", () => {
    window.location.reload();
  });
</script>

<style>
  main {
    margin: auto;
    padding: 1.5rem;
    max-width: 60ch;
  }
  h1 {
    font-size: 3rem;
    font-weight: 800;
    margin: 0;
  }
  .text-gradient {
    background-image: var(--accent-gradient);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-size: 400%;
    background-position: 0%;
  }
  .textfield {
    line-height: 1.6;
    margin: 1rem 0;
    border: 1px solid rgba(var(--accent), 25%);
    background-color: white;
    padding: 1rem;
    border-radius: 0.4rem;
    min-height: 320px;
    caret-color: transparent;
  }
  .textfield code {
    font-size: 0.875em;
    font-weight: bold;
    background: rgba(var(--accent), 12%);
    color: rgb(var(--accent));
    border-radius: 4px;
    padding: 0.3em 0.45em;
  }
  .textfield strong {
    color: rgb(var(--accent));
  }
  .link-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr));
    gap: 1rem;
    padding: 0;
  }
</style>
